import DataSet from './utils/dataset/dataSet'
import XLG from './utils/xlg/xlg'
import { exportExcel } from './utils/exportExcel'

let osAllFilesList = window.parent.window.filesList
let layer = window.parent.window.layer
let renderInitOs = window.parent.window.renderInit
let winui = window.parent.window.winui
let luckysheetUrl = window.parent.window.luckysheetUrl
let mainDomain = window.parent.window.mainDomain

let InnerObject = innerFunction()

export default {
  InnerObject
}

// 创建操作日志数据库
function createLogDB() {
  var request = window.indexedDB.open("xlgData", 1)
  var db
  request.onerror = function () {
    console.log("Why didn't you allow my web app to use IndexedDB?!")
  }
  request.onsuccess = function (event) {
    db = event.target.result
  }
  //创建表以及索引
  request.onupgradeneeded = function (event) {
    console.log('创建表以及索引')
    db = event.target.result;
    var objectStore = null;
    if (!db.objectStoreNames.contains('xlgDataStorage')) {
      //创建数据库实例
      objectStore = db.createObjectStore('xlgDataStorage', { keyPath: 'id', autoIncrement: true });//logTable对象仓库(表)，id为主键
    }
  }
}

// 存储xlg
function saveLog(xlgJson) {
  // 打开数据库
  let request = indexedDB.open('xlgData');
  // 请求数据库成功的回调函数
  request.onsuccess = function (success) {
    // 获取数据库实例对象
    let db = success.target.result;
    // 对某个表 进行事务操作的事务权限控制 
    let transaction = db.transaction('xlgDataStorage', 'readwrite');
    // 对表进行操作
    let objectStore = transaction.objectStore('xlgDataStorage');
    let data = {
      data: xlgJson,
      id: "xlg"
    }
    let add = objectStore.add(data);
    // 添加成功的回调函数
    add.onsuccess = function () {
      console.log('向表新增一条数据为成功！！');
      let res = objectStore.get("xlg")
      res.onsuccess = function (event) {
        console.log(event.target.result, '====================>indexedDB中存的数据')
      }
      let areaWidth = document.body.clientWidth + "px"
      let areaHeight = document.body.clientHeight + "px"
      let open_area = [areaWidth, areaHeight]
      let time = new Date().getTime()
      if (window.parent) {
        winui.window
        .config({
          anim: 0,
          miniAnim: 0,
          maxOpen: -1,
        })
        .open({
          id: `${mainDomain}-gongqi_tool_onlineForm-${time}`,
          icon: '<div class="winui-icon winui-icon-img" style=""><img src="/osweb/mixDomainIcons/gongqi.tool.onlineForm.png"></img></div>',
          type: 2,
          title: '表格编辑器',
          content: `${luckysheetUrl}?fileType=createXlg&openType=file&appId=gongqi.tool.onlineForm&domain=${mainDomain}&isJs=true`,
          area: open_area,
          skin: '',
          offset: ['0px', '0px'],
          resize: true,
          maxOpen: -1,
          max: true,
          min: true,
        }, null, true)
      }

    }
    add.onerror = function () {
      console.log('向表新增一条数据失败！！');
    }
  }
}

// 清空数据库
function clearLog(xlgJson) {
  // 打开数据库
  let request = indexedDB.open('xlgData')
  // 请求数据库成功的回调函数
  request.onsuccess = function (success) {
    // 获取数据库实例对象
    let db = success.target.result;
    // 对某个表 进行事务操作的事务权限控制 
    let transaction = db.transaction('xlgDataStorage', 'readwrite')
    // 对表进行操作
    let objectStore = transaction.objectStore('xlgDataStorage')
    let delRequest = objectStore.clear()
    delRequest.onsuccess = function () {
      saveLog(xlgJson)
      console.log('数据全部删除成功')
    }
    delRequest.onerror = function () {
      console.log('数据全部删除失败')
    }
  }
    // var request = objectStore.delete('xlg');
    // request.onsuccess = function (event) {
    //   saveLog(xlgJson)
    //   console.log('数据删除成功') 
    // }
    // request.onerror = function (event) {
    //   console.log('数据删除失败') 
    // }
}

function innerFunction() {
  // 初始化
  createLogDB()

  // 列字母转换为列号
  function stringTonum(a) {
    var str = a.toLowerCase().split("")
    var al = str.length;
    var getCharNumber = function (charx) {
      return charx.charCodeAt() - 96;
    };
    var numout = 0;
    var charnum = 0;
    for (var i = 0; i < al; i++) {
      charnum = getCharNumber(str[i]);
      numout += charnum * Math.pow(26, al - i - 1);
    }
    return numout;
  }

  /**
   * @description: 加载XLG
   * @param {String} path 文件路径
   * @param {String} userId 用户id
   * @return {Class} Class XLG
   */
  const loadXLG = function (path, userId) {
    let user
    if (userId) {
      user = userId
    } else {
      user = localStorage.getItem('userId')
    }
    var content
    $.ajax({
      method: "GET",
      url: `/file/openPurchFileByPath?path=${path}&userId=${user}`,
      contentType: "application/json",
      dataType: "JSON",
      async: false,
      headers: {
        token: localStorage.getItem("userToken"),
      },
      success: (res) => {
        if (res.success) {
          content = JSON.parse(res.result) 
          let options = {
            container: 'luckysheet1', // 设定DOM容器的id
            forceCalculation: true,
            title: content.title,
            data: content.content
          }
          luckysheet.create(options)
        } else {
          layer.msg(res.message, { zIndex: layer.zIndex })
        }
      }
    })
    let obj = new XLG(content)
    return obj
  }

  /**
   * @description: 打开xlg文件
   * @param {Class} xlgClass XLG Class 
   */
  const openXLG = function (xlgClass) {
    if (process.env.NODE_ENV !== 'production') {
      let xlg = {
        title: '默认',
        content: luckysheet.getAllSheets()
      }
      window.openXlg(xlg)
    } else {
      let xlg = {
        title: '默认',
        content: luckysheet.getAllSheets()
      }
      clearLog(xlg) // 清空数据库数据后添加
    }
  }

  /**
   * @description: 存储XLG文件
   * @param {Class} xlgClass XLG Class
   * @param {String} path 文件路径
   * @return {*} 无
   */
  const saveXLG = function (xlgClass, path) {
    let content = {
      title: xlgClass.title,
      content: luckysheet.getAllSheets()
    }
    let file = null
    osAllFilesList.forEach(item => {
      let filePath = `${item.filePath}/${item.name}${item.suffix}`
      if (filePath === path) {
        file = item
      }
    })
    if (file) {
      // 文件已有
      $.ajax({
        method: "POST",
        url: `/MIX/web/apps/gongqi.tool.onlineForm/file/saveOSFile?gongqiFileId=${file.gongQiFileId}`,
        contentType: "application/json",
        dataType: "JSON",
        async: false,
        data: JSON.stringify(content),
        headers: {
          token: localStorage.getItem("userToken"),
        },
        success: (res) => {
          if (res.code === 200) {
            renderInitOs('refresh')
            layer.msg('保存成功', { zIndex: layer.zIndex })
          } else {
            layer.msg(res.message, { zIndex: layer.zIndex })
          }
        }
      })
    } else {
      // 文件不存在，新建xlg
      let list = path.split('/')
      let name = list[list.length - 1]
      list.pop()
      let pathString = list.join('/')
      let params = {
        fileModeltype: 0,
        filePath: pathString,
        gongQiFileId: "",
        name: name.split('.')[0],
        newName: name.split('.')[0],
        suffix: `.${name.split('.')[1]}`,
        content: JSON.stringify(content)
      }
      $.ajax({
        type: "POST",
        async: false,
        dataType: "JSON",
        url: '/file/createFile',
        contentType: "application/json",
        data: JSON.stringify(params),
        headers: {
          token: localStorage.getItem("userToken"),
        },
        success: (res) => {
          if (res.success) {
            console.log('创建文件成功')
            layer.msg('保存成功', {
              zIndex: layer.zIndex,
            })
            renderInitOs('refresh')
          } else {
            layer.msg(res.message, { zIndex: layer.zIndex })
          }
        }
      })
    }
  }

  /**
   * @description: 得到DS文件内容
   * @param {String} dataSetName 
   * @param {Object} dataSetParams
   * @return {Object} Class DataSet
   */
  const queryDataView = async function (dataSetName, dataSetParams) {
    var content = null
    let params = {
      dataSetName,
      dataSetParams
    }
    return new Promise(resolve => {
      $.ajax({
        method: "POST",
        url: '/MIX/web/apps/gongqi.tool.datasetDesign/dsDesign/loadDataView',
        contentType: "application/json",
        dataType: "JSON",
        async: true,
        data: JSON.stringify(params),
        headers: {
          token: localStorage.getItem("userToken"),
        },
        success: (res) => {
          if (res.errcode === 0) {
            content = new DataSet(res.content)
            resolve(content)
            // content = JSON.parse(res.content)
          } else {
            layer.msg(res.message, { zIndex: layer.zIndex })
          }
        }
      })
    })
  }

  /**
   * @description: 插入列
   * @param {Object} xlgJson 
   * @param {Number} columnIndex 列号
   * @param {Number} number 数量
   * @param {Number} order 工作表下标
   * @return {Object} xlgJson
   */
  const insertColumn = function (xlgJson, columnIndex, number = 1, order = 0) {
    let colIndex = stringTonum(columnIndex)
    luckysheet.setSheetActive(order)
    luckysheet.setRangeShow("A1:BH100", { show: false, order })
    luckysheet.insertColumn(colIndex, { number, order })
    return {}
  }

  /**
   * @description: 复制
   * @param {Object} xlgJson
   * @param {String | Object} range 区间
   * @param {Number} order 工作表下标
   * @return {Object} xlgJson
   */
  const getRangeValue = async function (xlgJson, range, order = 0) {
    let xlgJsonData = luckysheet.getAllSheets()
    luckysheet.setFlowdata(xlgJsonData[order].data)
  }

  /**
   * @description: 获取区间值
   * @param {Object} xlgJson
   * @param {String | Object} range 区间
   * @param {Number} order 工作表下标
   * @return {Array} 区间值list
   */
    const getRangeValueList = function (range, order = 0) {
      return luckysheet.getRangeValue({range, order})
    }

  /**
   * @description: 粘贴
   * @param {Object} xlgJson
   * @param {String} range 复制区间
   * @param {String} pasteRange 粘贴区间
   * @param {Boolean} isMerge 复制区间是否有合并单元格
   * @param {Number} order 工作表下标
   * @return {Object} xlgJson
   */
  const setRangeValue = async function (xlgJson, range, pasteRange, isMerge = false, order = 0) {
    // 复制区域
    let colList = range.split(/[^a-zA-Z]/g).filter(item => {
      return item !== ""
    })
    let rowList = range.split(/[^\d]/g).filter(item => {
      return item !== ""
    })
    let column = []
    let row = []
    colList.forEach(item => {
      column.push(Number(stringTonum(item)) - 1)
    })
    rowList.forEach(item => {
      row.push(Number(item) - 1)
    })
    let copyStartRow = Number(rowList[0])
    let copyStartCol = Number(stringTonum(colList[0]))
    let copyEndRow = Number(rowList[1])
    let copyEndCol = Number(stringTonum(colList[1]))
    let copyRowNum = copyEndRow - copyStartRow + 1
    let copyColNum = copyEndCol - copyStartCol + 1
    var copyRange = {
      dataSheetIndex: order,
      copyRange: [{ column, row }],
      isMerge
    }

    // 粘贴区域
    let pasteRowList = pasteRange.split(/[^\d]/g).filter(item => {
      return item !== ""
    })
    let pasteColList = pasteRange.split(/[^a-zA-Z]/g).filter(item => {
      return item !== ""
    })
    let stateRow = Number(pasteRowList[0])
    let startCol = Number(stringTonum(pasteColList[0]))
    let endRow = Number(pasteRowList[1])
    let endCol = Number(stringTonum(pasteColList[1]))
    let allRowNum = endRow - stateRow + 1
    let allColNum = endCol - startCol + 1
    let pasteRowTime = allRowNum / copyRowNum
    let pasteColTime = allColNum / copyColNum
    luckysheet.selection.paste2(copyRange, startCol, pasteColTime, stateRow, pasteRowTime)
  }

  /**
   * @description: 得到单元格的值
   * @param {Object} xlgJson
   * @param {Number} rowIndex 行号
   * @param {Number} columnIndex 列号
   * @param {Number} order 工作表下标
   * @return {Object} val 单元格的值
   */
  const getCellValue = function (xlgJson, rowIndex, columnIndex, order = 0) {
    let colIndex = stringTonum(columnIndex)
    luckysheet.setSheetActive(order)
    luckysheet.setRangeShow("A1:BH100", { show: false, order })
    let val = luckysheet.getCellValue(rowIndex - 1, colIndex - 1, { order })
    return val
  }

  /**
   * @description: 设置单元格的值
   * @param {Object} xlgJson
   * @param {Number} rowIndex 行号
   * @param {Number} colIndex 列号
   * @param {*} value 设置值
   * @param {Number} order 工作表下标
   * @return {Object} xlgJson
   */
  const setCellValue = function (xlgJson, rowIndex, columnIndex, value, order = 0) {
    let colIndex = stringTonum(columnIndex)
    luckysheet.setSheetActive(order)
    luckysheet.setRangeShow("A1:BH100", { show: false, order })
    let xlgJsonData = luckysheet.getAllSheets()
    luckysheet.setFlowdata(xlgJsonData[order].data)
    luckysheet.setCellValue(rowIndex - 1, colIndex - 1, value, { order })
    return {}
  }

  /**
   * @description: 隐藏行
   * @param {Object} xlgJson
   * @param {Number} rowStart 起始行
   * @param {Number} rowEnd 结束行
   * @param {Number} order 工作表下标
   * @return {Object} xlgJson
   */
  const hideRow = function (xlgJson, rowStart, rowEnd, order = 0) {
    luckysheet.setSheetActive(order)
    luckysheet.setRangeShow("A1:BH100", { show: false, order })
    luckysheet.hideRow(rowStart - 1, rowEnd - 1, { order })
    return {}
  }

  /**
   * @description: 打开还是关闭筛选功能
   * @param {Object} xlgJson
   * @param {String} type 是否开启
   * @param {String} range 范围
   * @param {Number} order 工作表下标
   * @return {Object} xlgJson
   */
  const setRangeFilter = function (xlgJson, type = 'open', range = 'A1:A2', order = 0) {
    luckysheet.setSheetActive(order)
    luckysheet.setRangeShow("A1:BH100", { show: false, order })
    luckysheet.setRangeFilter(type, { range, order })
    return {}
  }

  /**
   * @description: 在行之前插入
   * @param {Object} xlgJson
   * @param {Number} rowIndex 行号
   * @param {Number} number 数量
   * @param {Number} order 工作表下标
   * @return {Object} xlgJson
   */
  const insertRowBefore = function (xlgJson, rowIndex, number = 1, order = 0) {
    luckysheet.setSheetActive(order)
    // luckysheet.setRangeShow("A1:BH100", { show: false, order })
    let index = 0
    switch (rowIndex) {
      case 0:
        index = 0
        break;
      case 1:
        index = 0
        break
      default:
        index = rowIndex - 1
    }
    luckysheet.insertRow(index, { number, order })
    return {}
  }

  /**
   * @description: 在行之后插入
   * @param {Object} xlgJson
   * @param {Number} rowIndex 行号
   * @param {Number} number 数量
   * @param {Number} order 工作表下标
   * @return {Object} xlgJson
   */
  const insertRowAfter = function (xlgJson, rowIndex, number = 1, order = 0) {
    luckysheet.setSheetActive(order)
    // luckysheet.setRangeShow("A1:BH100", { show: false, order })
    luckysheet.insertRow(rowIndex, { number, order })
    return {}
  }

  /**
   * @description: 删除行
   * @param {Object} xlgJson
   * @param {Number} rowStart 起始行
   * @param {Number} rowEnd 结束行
   * @param {Number} order 工作表下标
   * @return {Object} xlgJson
   */
  const deleteRow = function (xlgJson, rowStart, rowEnd, order = 0) {
    luckysheet.setSheetActive(order)
    luckysheet.Store.luckysheet_selection_range = [];
    luckysheet.setRangeShow("A1:BH100", { show: false, order })
    let xlgJsonData = luckysheet.getAllSheets()
    luckysheet.setFlowdata(xlgJsonData[order].data)
    luckysheet.deleteRow(rowStart - 1, rowEnd - 1, { order })
    return {}
  }

  /**
   * @description: 设置单元格的值方法2
   * @param {Object} xlgJson
   * @param {Number} rowIndex 行号
   * @param {Number} columnIndex 列号
   * @param {*} value 设置值
   * @param {Number} order 工作表下标
   * @return {Object} xlgJson
   */
  const setCellValue2 = function (xlgJson, rowIndex, columnIndex, value = '', order = 0) {
    let colIndex
    if (typeof columnIndex !== 'number') {
      colIndex = stringTonum(columnIndex)
    } else {
      colIndex = columnIndex
    }
    luckysheet.setCellValue(rowIndex - 1, colIndex - 1, value, { order, clearF:true })
    return null
  }

  /**
   * @description: 设置单元格的值方法3
   * @param {Object} xlgJson
   * @param {String} cell 单元格
   * @param {*} value 设置值
   * @param {Number} order 工作表下标
   * @return {Object} xlgJson
   */
  const setCellValue3 = function (xlgJson, cell, value = '', order = 0) {
    let colList = cell.split(/[^a-zA-Z]/g).filter(item => {
      return item !== ""
    })
    let rowList = cell.split(/[^\d]/g).filter(item => {
      return item !== ""
    })
    let rowIndex = Number(rowList[0])
    let colIndex = stringTonum(colList[0])
    luckysheet.setCellValue(rowIndex - 1, colIndex - 1, value, { order, clearF:true })
    return null;
  }

  /**
   * @description: 设置列宽
   * @param {Object} colWidthObj 列宽参数 {1: 100, 2: 500} / {a: 100, b: 500}
   * @param {Number} order 工作表下标
   */
  const setColumnWidth = function (colWidthObj, order) {
    let params = {}
    for (const key in colWidthObj) {
      let colIndex
      if (isNaN(key)) {
        colIndex = stringTonum(key) - 1
      } else {
        colIndex = Number(key) - 1
      }
      if (colIndex < 0) {
        throw new Error('列号为正整数, 请重新确认列号')
      }
      params[colIndex] = colWidthObj[key]
    }
    luckysheet.setColumnWidth(params, {order})
  }

	/**
	 * @description: 选定的范围开启多列自定义排序功能
	 * @param {Array} sort 列设置，设置需要排序的列索引和排序方式，格式如：[{ i:1,sort:'asc' },{ i:'B',sort:'des' }]
	 * @param {String} range 选区范围,支持选区的格式
	 */
  const sort = function (sort, range, order) {
    sort.forEach(item => {
      if (typeof item.i === 'number') {
        item.i -= 1
      } else {
        item.i = stringTonum(item.i) - 1
      }
      if (!item.sort) {
        item.sort = 'asc'
      }
    })
		luckysheet.setRangeSortMulti(false, sort, {range, order})
	}

  // 导出xlsx
  const exportXLSX = async function (xlgJson) {
    let content = luckysheet.getAllSheets()
    let buffer = await exportExcel(content)
    let obj = new File([buffer], 'xlg文件', { type: 'application/vnd.ms-excel' });
    var tmpa = document.createElement("a");
    let h = new Date().getHours()
    let m = new Date().getMinutes()
    let s = new Date().getSeconds()
    tmpa.download = `${xlgJson.title || '未命名'}_${h}${m}${s}.xlsx`;
    tmpa.href = URL.createObjectURL(obj);
    tmpa.click()
  }

  // 强制刷新公式
  const refreshFormula = function () {
    luckysheet.refreshFormula()
  }

  const getBeginYearDay = function (date) {
    var year = date.getFullYear();
    return new Date(year + "-01-01");
  }

  const getBeginMonthDay = function (date) {
    var year = date.getFullYear();
    var month = (date.getMonth() + 1).toString();
    if (month.length == 1) {
        month = "0" + month;
    }
    return new Date(year + "-" + month + "-01");
  }

  const getEndMonthDay = function (date) {
      var year = date.getFullYear();
      var month = (date.getMonth() + 1).toString();
      return new Date(year, month, 0);
  }

  const formatDate = function (date) {
    var year = date.getFullYear();
    var month = (date.getMonth() + 1).toString();
    var day = (date.getDate()).toString();
    if (month.length == 1) {
        month = "0" + month;
    }
    if (day.length == 1) {
        day = "0" + day;
    }
    var dateTime = year + "-" + month + "-" + day;
    return dateTime;
}

  // 注册全局方法
  window.codelist = {
    loadXLG,
    saveXLG,
    queryDataView,
    insertColumn,
    getRangeValue,
    setRangeValue,
    getCellValue,
    setCellValue,
    hideRow,
    setRangeFilter,
    insertRowBefore,
    insertRowAfter,
    deleteRow,
    openXLG,
    setCellValue2,
    setCellValue3,
    setColumnWidth,
    exportXLSX,
    refreshFormula,
    getRangeValueList,
    getBeginYearDay,
    getBeginMonthDay,
    getEndMonthDay,
    formatDate,
    sort
  }
}